#pragma once

#include "FastDelegate.h"
#include <memory>

class IEvent;
typedef unsigned long EventType;
typedef std::shared_ptr<IEvent> IEventPtr;
typedef fastdelegate::FastDelegate1<IEventPtr> EventListenerDelegate;

class IEvent
{
public:
	virtual const EventType& VGetEventType() const = 0;
	virtual double GetTimeStamp() const = 0;

};

class BaseEvent : public IEvent
{
	const double m_timeStamp;

public:
	explicit BaseEvent(const double timeStamp = 0.0) : m_timeStamp(timeStamp) { }
	virtual ~BaseEvent() {}

	virtual const EventType& VGetEventType() const = 0;

	double GetTimeStamp() const { return m_timeStamp; }
};

class IEventManager
{
public:
	enum eConstants { kINFINITE = 0xffffffff };

	explicit IEventManager(const char* pName, bool global);
	virtual ~IEventManager();

	virtual bool VAddListener(const EventListenerDelegate& eventDelegate, const EventType& type) = 0;
	virtual bool VRemoveListener(const EventListenerDelegate& eventDelegate, const EventType& type) = 0;
	virtual bool VTriggerEvent(const IEventPtr& pEvent) const = 0;
	virtual bool VQueueEvent(const IEventPtr& pEvent) = 0;
	virtual bool VThreadSafeQueueEvent(const IEventPtr& pEvent) = 0;
	virtual bool VAbortEvent(const EventType& inType, bool all = false) = 0;
	virtual bool VUpdate(unsigned long maxMillis = kINFINITE) = 0;

	static IEventManager* Get();
};